package interfaz;

import java.util.logging.Level;
import java.util.logging.Logger;
import juego.*;
import objetos.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.ArrayList;
import javax.swing.JFileChooser.*;
import javax.swing.filechooser.FileFilter.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import objetos.personajes.Bando;

/** @author Carlos && Miguel && Yanire && Cesar ;)**/
public class LaVentana extends JFrame {

    static final public int alto = 700;
    static final public int ancho = 800;
    static final private int INICIO = 1;
    static final private int JUEGO = 2;
    static final private int INSTRUCCIONES = 3;
    static final private int OBJETIVOS = 4;
    static final private int CREDITOS = 5;
    static final private int FIN = 6;
    public int tiempo = INICIO;
    private Juego juego = new Juego();
    private boolean esFinJuego = false;
    private BufferStrategy bufferStrategy;
    private String mensajeManutencion = "";
    private PopupMenu popup;
    private Menu menu;
    private Instrucciones inst;
    private Objetivos obj;
    private Creditos cred;
    public HiloPadre hiloE;
    public ArrayList<HiloEnemigo> hiloList = new ArrayList<HiloEnemigo>();

    public LaVentana() {

        
        hiloE = new HiloPadre(this, "HILO PADRE");
        //hiloE.start();

        setBounds(150, 0, ancho, alto);
        setTitle("Incan Empires II: The Empire Strikes Back");
        setLayout(null);
        this.setBackground(Color.black);
        this.setResizable(false);
        //setLocationRelativeTo(null);

        inicializacion();

        //agregando a la ventana
        add(menu);
        add(inst);
        add(obj);
        add(cred);
        add(popup);

        

        //Todos los listener
        menu.getJugar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(false);
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(false);
                getJuego().getJugador(LaVentana.this);
                tiempo = JUEGO;
                repaint();
                HiloManutencion hiloManu = new HiloManutencion(getJuego().getGestor().getBandos(), LaVentana.this);
                hiloManu.start();
                hiloE.start();
            }
        });

        menu.getCargar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(false);

                JFileChooser chooser = new JFileChooser("./savedGames");
                FileNameExtensionFilter filter = new FileNameExtensionFilter("*.xml & *.txt", "xml", "txt");

                chooser.setFileFilter(filter);
                int returnVal = chooser.showOpenDialog(new JDialog());
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    getJuego().deserializar(chooser.getSelectedFile().getPath());
                    menu.setVisible(false);
                    tiempo = JUEGO;
                    repaint();
                } else {
                    menu.setVisible(true);
                }

            }
        });

        popup.getComprarArmas().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
              

                popup.setVisible(false);
                repaint();
                
                int dir = getJuego().getDirAldea();
                getJuego().comprarArmas(dir, LaVentana.this);

            }
        });

        popup.getComprarPersonajes().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                
                popup.setVisible(false);
                repaint();

                int dir = getJuego().getDirAldea();
                getJuego().comprarPersonajes(dir, LaVentana.this);
            }
        });

        //  <editor-fold defaultstate="collapsed" desc="Listener muy simples">

        menu.getInstrucciones().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(false);
                inst.setVisible(true);
                obj.setVisible(false);
                cred.setVisible(false);

            }
        });

        menu.getObjetivos().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(false);
                inst.setVisible(false);
                obj.setVisible(true);
                cred.setVisible(false);
            }
        });

        menu.getCreditos().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(false);
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(true);
            }
        });

        menu.getSalir().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        inst.getVolver().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(true);
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(false);
            }
        });

        obj.getVolver().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(true);
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(false);
            }
        });

        cred.getVolver().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                menu.setVisible(true);
                inst.setVisible(false);
                obj.setVisible(false);
                cred.setVisible(false);
            }
        });

        //  </editor-fold>

        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent evt) {
                int dir = 0;

                Graphics g = LaVentana.this.getGraphics();

                if (tiempo == JUEGO) {
                    //  <editor-fold defaultstate="collapsed" desc="Movimiento Jugador">

                    dir = getJuego().getDirMouse(evt.getX(), evt.getY());

                    //Si se dio click izquierdo
                    if (evt.getButton() == MouseEvent.BUTTON1) {
                        if (getJuego().hayEnemigoAdyacente(dir)) {
                            esFinJuego = getJuego().atacar(dir);
                        } else if (!juego.hayAldeaAdyacente(dir)) {
                            getJuego().mover(dir);
                        }
//                        HiloManutencion hiloManu = new HiloManutencion(getJuego().getGestor().getBandos(), LaVentana.this);
//                        hiloManu.start();
                        //mensajeManutencion = getJuego().getManutencion();
                        getJuego().getCuracion();

                        LaVentana.this.update(g);

                        if (esFinJuego) {
                            if (getJuego().cambiarNivel() == false) {
                                getJuego().imprimirFinJuego(LaVentana.this);
                                tiempo = FIN;
                                return;
                            }
                        }
                        //  </editor-fold>

                    }

                    //Si se dio click derecho
                    if (evt.getButton() == MouseEvent.BUTTON3) {

                        if (getJuego().hayEnemigoAdyacente()) {
                            esFinJuego = getJuego().atacar(dir);
                        } else if (juego.hayAldeaAdyacente(dir)) {

                            if ((dir = getJuego().getDirAldea()) != 0) {
                                //realiza la compra con click derecho
                                //solo si se da click sobre la aldea
                                int[] celda = getJuego().inMouseOutCelda(evt.getX(), evt.getY());

                                if (getJuego().getContentCelda(celda[0], celda[1]) instanceof Aldea) {

                                    popup.show(evt.getComponent(), evt.getX(), evt.getY());

                                    getJuego().getCuracion();

                                    LaVentana.this.update(g);

                                    if (esFinJuego) {
                                        if (getJuego().cambiarNivel() == false) {
                                            getJuego().imprimirFinJuego(LaVentana.this);
                                            tiempo = FIN;
                                            LaVentana.this.dispose();
                                            return;
                                        }
                                    }
                                    //  </editor-fold>
                                } else {
                                    JOptionPane.showMessageDialog(LaVentana.this, "No ha dado click sobre la aldea,\n"
                                            + "vuelva a jugar.", "Compras", JOptionPane.INFORMATION_MESSAGE);
                                }
                            }
                        } else {
                            JOptionPane.showMessageDialog(LaVentana.this, "No hay una aldea adyacente,\n"
                                    + "vuelva a jugar.", "Compras", JOptionPane.INFORMATION_MESSAGE);
                        }
                    }
                    //  <editor-fold defaultstate="collapsed" desc="Cambios de pantalla">
                    switch (tiempo) {
                        case INICIO:
                            tiempo = INSTRUCCIONES;
                            break;
                        case INSTRUCCIONES:
                            tiempo = JUEGO;
                            break;
                    }

                    //  </editor-fold>
                }

                LaVentana.this.update(g);

            }

            @Override
            public void mousePressed(MouseEvent evt) {
                juego.getGestor().setCoordenadasInicio(evt.getX(), evt.getY());
            }

            @Override
            public void mouseReleased(MouseEvent evt) {
                juego.getGestor().setCoordenadasFin(evt.getX(), evt.getY());
                Graphics g = LaVentana.this.getGraphics();
                juego.getGestor().crearSeleccionado();
                LaVentana.this.update(g);

            }
        });

        this.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent evt) {
                int dir = 0;
                int code = evt.getKeyCode();

                Graphics g = LaVentana.this.getGraphics();

                if (tiempo == JUEGO) {
                    if (code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_LEFT) {
                        //  <editor-fold defaultstate="collapsed" desc="Movimiento Jugador">

                        switch (code) {
                            case KeyEvent.VK_UP:
                                dir = 12;
                                break;
                            case KeyEvent.VK_DOWN:
                                dir = 6;
                                break;
                            case KeyEvent.VK_RIGHT:
                                dir = 3;
                                break;
                            case KeyEvent.VK_LEFT:
                                dir = 9;
                                break;
                        }

                        if (getJuego().hayEnemigoAdyacente(dir)) {
                            esFinJuego = getJuego().atacar(dir);
                        } else if (!juego.hayAldeaAdyacente(dir)) {
                            getJuego().mover(dir);
                        } else {
                            
                            popup.show(evt.getComponent(), 380, 250);
                            popup.setVisible(true);
                        }

                        getJuego().getCuracion();

                        LaVentana.this.update(g);

                        if (esFinJuego) {
                            hiloE.setMurio(true);
                            hiloE.interrupt();
                            if (getJuego().cambiarNivel() == false) {
                                getJuego().imprimirFinJuego(LaVentana.this);
                                tiempo = FIN;
                                LaVentana.this.dispose();
                                return;
                            }
                        }
                        //  </editor-fold>

                    }
                    if (code == KeyEvent.VK_SPACE) {
                        juego.getGestor().deseleccionar();
                        LaVentana.this.update(g);
                        getJuego().cambiar();
                        LaVentana.this.update(g);
                    }
                    if (code == KeyEvent.VK_ESCAPE) {
                        if (!popup.isVisible()) {
                            repaint();
                        }
                        PopUp popup = new PopUp(LaVentana.this, true);
                    }
                }
                LaVentana.this.update(g);
            }
        });

        setVisible(true);
        createBufferStrategy(2);
        bufferStrategy = getBufferStrategy();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void paint(Graphics g) {
        switch (tiempo) {
            case INICIO:
                paintComponents(g);
                break;
            case JUEGO:
                dibujarJuego(g);
                break;
        }
    }

    public void dibujarJuego(Graphics g) {
        Graphics2D graph2D = (Graphics2D) bufferStrategy.getDrawGraphics();
        switch (tiempo) {
            case JUEGO:
                graph2D.clearRect(0, 0, ancho, alto);
                getJuego().MostrarMapa(graph2D, this);
                //  <editor-fold defaultstate="collapsed" desc="Impresion Info.">
                graph2D.setColor(Color.white);
                Font font = new Font("Sans_Serif", Font.BOLD, 14);
                graph2D.setFont(font);

                graph2D.drawString("Nivel:   " + juego.getGestor().getNivel(), 20, 100);
                graph2D.drawString("Batalla: " + juego.getGestor().getMapa().getNombre(), 20, 50);

                for (int i = 0; i < 5; i++) {
                    graph2D.drawString(getJuego().sacarInfoBando2(i), 10, 530 + (i * 14));
                }

                for (int i = 5, j = 0; i < 10; i++, j++) {
                    graph2D.drawString(getJuego().sacarInfoBando2(i), 350, 530 + (j * 14));
                }

                for (int i = 10, j = 0; i < 16; i++, j++) {
                    graph2D.drawString(getJuego().sacarInfoBando2(i), 600, 530 + (j * 14));
                }

                graph2D.setColor(Color.white);
                Bando miBando = getJuego().getGestor().getBandos()[getJuego().getGestor().getTurnoJugador()];
                Bando tuBando = getJuego().getGestor().getBandos()[getJuego().getGestor().getRival()];
                graph2D.setColor(Color.green);


                graph2D.setColor(Color.green);
                graph2D.drawString("Para cambiar de personaje presione ESPACE", 400, 660);
                graph2D.drawString("Para salir presione ESC", 400, 688);

                graph2D.setColor(Color.blue);
                graph2D.drawString(getMensajeManutencion(), 10, 660);

                graph2D.setColor(Color.red);
                graph2D.drawString(getJuego().getAtacar(), 10, 680);
                //  </editor-fold>
                break;
            case FIN:
                dispose();
                break;
        }
        bufferStrategy.show();
    }

    public final void inicializacion() {
        menu = new Menu();
        inst = new Instrucciones();
        obj = new Objetivos();
        cred = new Creditos();
        popup = new PopupMenu();

        //configuracion de tamaños
        menu.setBounds(0, 0, ancho, alto);
        inst.setBounds(0, 0, ancho, alto);
        obj.setBounds(0, 0, ancho, alto);
        cred.setBounds(0, 0, ancho, alto);


        //configuracion de visibilidad
        menu.setVisible(true);
        inst.setVisible(false);
        obj.setVisible(false);
        cred.setVisible(false);


    }

    @Override
    public boolean isFocusable() {
        return true;
    }

    /**
     * @return the juego
     */
    public Juego getJuego() {
        return juego;
    }

    /**
     * @return the mensajeManutencion
     */
    public String getMensajeManutencion() {
        return mensajeManutencion;
    }

    /**
     * @param mensajeManutencion the mensajeManutencion to set
     */
    public void setMensajeManutencion(String mensajeManutencion) {
        this.mensajeManutencion = mensajeManutencion;
    }
}
